﻿using EF6Query.DBModel;
using EF6Query.Models.ViewModel;
using ExpressionBuilder.Helpers;
using ExpressionBuilder.Interfaces;
using ExpressionBuilder.Resources;
using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection;
using System.Xml.Linq;

namespace EF6Query.Models.Common
{
    public class DBEntityType
    {

        private IPropertyCollection _properties;
        private OperationHelper operationHelper = new OperationHelper();

        /// <summary>
        /// 获取表名和类型的关系
        /// </summary>
        public static Dictionary<string, Type> EntityPermissionTypes = new()
        {
            { "Product",typeof(Product) },
            { "ProductColor",typeof(ProductColor) }
        };

        public IPropertyCollection LoadProperties(Type type)
        {
            _properties = new PropertyCollection(type);
            return _properties;
        }


        public DBEntityType()
        {
            if (!EntityPermissionTypes.Any())
            {
                Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.FullName.Contains("EF6")).ToArray();
                foreach (Assembly assembly in assemblies)
                {
                    var tableTypes = assembly.GetTypes().Where(type => type.IsClass && type.GetCustomAttribute<TableAttribute>() != null).ToList();
                    tableTypes.ForEach(type =>
                    {
                        if (type == null)
                        {
                            var tableAttribute = type.GetCustomAttribute<TableAttribute>();
                            if (!string.IsNullOrEmpty(tableAttribute?.Name))
                                EntityPermissionTypes.Add(tableAttribute.Name, type);
                        }
                    });
                }
            }
        }


        public List<TablePropertyInfo> GetTypePropertyInfo(string tableName)
        {
            var result = new List<TablePropertyInfo>();
            Assembly assembly = Assembly.GetEntryAssembly();
            // 替换为程序集所在文件夹的路径
            string xmlFilePath = Path.ChangeExtension(assembly.Location, ".xml");
            EntityPermissionTypes.TryGetValue(tableName, out var type);
            if (type != null)
            {
                PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);

                foreach (var property in properties)
                {
                    string propertyName = property.Name;
                    string propertySummary = GetPropertySummary(xmlFilePath, property);
                    result.Add(new TablePropertyInfo
                    {
                        PropertyName = propertyName,
                        PropertySummary = propertySummary,
                        PropertyType = property.PropertyType,
                        PropertyTypeName = property.PropertyType.Name,
                    });
                }
            }
            return result;
        }



        public List<TablePropertyInfo> GetTypePropertyByTableName(string tableName)
        {
            var result = new List<TablePropertyInfo>();
            Assembly assembly = Assembly.GetEntryAssembly();
            var location = assembly.Location.Replace("WebEasyUI.dll", "EF6Query.dll");
            // 替换为程序集所在文件夹的路径
            string xmlFilePath = Path.ChangeExtension(location, ".xml");
            EntityPermissionTypes.TryGetValue(tableName, out var type);
            if (type != null)
            {
                PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                foreach (var property in properties)
                {
                    string propertyName = property.Name;
                    string propertySummary = GetPropertySummary(xmlFilePath, property);
                    result.Add(new TablePropertyInfo
                    {
                        PropertyName = propertyName,
                        PropertySummary = propertySummary,
                        PropertyTypeName = property.PropertyType.Name,
                    });
                }
            }
            return result;
        }

        static string GetPropertySummary(string xmlFilePath, PropertyInfo property)
        {
            if (File.Exists(xmlFilePath))
            {
                string memberName = $"P:{property?.DeclaringType?.FullName}.{property?.Name}";
                XDocument xdoc = XDocument.Load(xmlFilePath);
                var memberElement = xdoc?.Element("doc")?.Element("members")?.Elements("member").FirstOrDefault(e => e?.Attribute("name")?.Value == memberName);
                if (memberElement != null)
                {
                    XElement summaryElement = memberElement?.Element("summary");
                    return summaryElement?.Value.Trim() ?? "No summary available.";
                }
            }
            return "No summary available.";
        }

        public object GetValue(string tableName, string propertyName, string val)
        {
            var propertyInfos = GetTypePropertyInfo(tableName);
            if (!string.IsNullOrEmpty(propertyName))
            {
                var property = propertyInfos.FirstOrDefault(x => x.PropertyName == propertyName);
                var type = property?.PropertyType;
                if (type == typeof(string)) return val;
                if (type == typeof(DateTime)) return DateTime.Parse(val);
                if (type == typeof(int)) return Convert.ToInt32(val);
                if (type == typeof(bool)) return bool.Parse(val);
                if (type.IsEnum) return Enum.ToObject(property.GetType(), val);
            }
            return null;
        }

    
    }
}
